using UnityEngine;
using System.Collections;

public class Controller : CanTakeDamage
{
	//Debug Variables
	public float playerSpeed = 5.0f;
	public float initalFirerate;
	public float fireRate = 5.0f;
	public float firerateMultiplier = 0.0f;
	public static bool initialShot = true;
	private bool evaded = false;
	private int dmgTaking = 0;
	private int startingHealth;
	private int armor = 0;
	float evasion = 0.0f;
	
	//Test varibable
	public bool canShoot = true;

    private GameObject spawnerRoot;
	private Vector3 mDirection;
	public GameObject gameBullet, gameRocket, gameVortex, gameCluster;
	private float mTimer, vortexTimer, shottyTimer = 0.0f, secondaryTimer = 0.0f, reloadMax;
	private Vector3 screenPoint2 = Vector3.zero;
	private Vector3 clickpoint = Vector3.zero;
	private Vector3 offset2;
	private GameObject vortex;
	private GameObject clusterbomb;
	private GameObject reloadBar, GO;
	public enum mainAttacks { Laser, Multilaser, Shottylaser };
	public enum secondaryAttacks { Rocket, Clusterbomb, Vortex };
	public static mainAttacks mainAttack = mainAttacks.Laser;
	public static secondaryAttacks secondaryAttack = secondaryAttacks.Rocket;
	private float offSetX = 270;
	private float offSetY = 0;
	private float offSetZ = 0;
	private float offSetX2 = 90;
	private float offSetY2 = 180;
	public static bool onStart = true;
	public GameObject explosion1;
	public static int currHealthBoost = 0;
	// Update is called once per frame
	public static bool shootSecondary = true;
	private Vector3 screenPoint;
	private Vector3 offset;
	private Vector3 TouchPosition;
	private Vector3 TouchPosition2;
	private Vector3 positionOffset;
    public int doubleDamage = 5;

	public Texture2D shipReg;
	public Texture2D shipGold;
	public Texture2D shipSparta;
	public Texture2D shipB2;
	public WeaponReload reload;
	private float initialHbarWidth;
    private float initialRbarWidth;
	//Debug variables
	
	
	
	[System.Serializable]
    public class WeaponReload
    {
		public float rocket = 2f;
		public float vortex = 15f;
        public float cluster = 5f;
		public string clusters = "live time on clusters script + cluster value";
    }
	protected override void Start()
	{
        //GO = GameObject.FindGameObjectWithTag("health");
        //initialHbarWidth = GO.guiTexture.pixelInset.width; 
        
        initialShot = true;
		//reload.cluster += cluster ;
        if (PlayerPrefs.GetInt("Support") > 0)
        {
            gameObject.transform.GetChild(0).gameObject.SetActive(true);
        }

		reloadBar = GameObject.FindGameObjectWithTag("reload");
		initialRbarWidth = reloadBar.guiTexture.pixelInset.width; 
		if(PlayerPrefs.GetString("PlayerShip") == "Regs")
		{
			transform.renderer.material.mainTexture = shipReg;
			//gameObject.renderer.material.mainTexture = shipReg;
		}
		if(PlayerPrefs.GetString("PlayerShip") == "B2Bomber"){
			transform.renderer.material.mainTexture = shipB2;
			transform.localRotation = Quaternion.Euler(new Vector3(0, 270, 90));
		}
		if(PlayerPrefs.GetString("PlayerShip") == "Goldy"){
			transform.renderer.material.mainTexture = shipGold;
		}
		if(PlayerPrefs.GetString("PlayerShip") == "ThisIsSparta")
        {
			transform.renderer.material.mainTexture = shipSparta;
		}
		if (onStart || !PlayerPrefs.HasKey("FireRate"))
		{
			initalFirerate = fireRate;
		}
			firerateMultiplier = PlayerPrefs.GetInt("FireRate") / 5;
			fireRate = initalFirerate - firerateMultiplier * .01f;
		
		if (onStart || !PlayerPrefs.HasKey("HealthBoost"))
		{
			//shootSecondary = true;
			initalHealth = Health;
			startingHealth = Health;
			base.Start();
			return;
		}
		startingHealth = Health;
		Health = initalHealth + PlayerPrefs.GetInt("HealthBoost");
		CurrHealth += (Health - startingHealth);
		onStart = false;
	}
    public void AddHealth()
    {
        if ((CurrHealth + 1) < Health)
        {
         //   print("2");
            CurrHealth += 1;
        }
        else
        {
            CancelInvoke();
        }

    }
    public void Heal()
    {
        InvokeRepeating("AddHealth",.5f, .01f);
    }

	void Update()
	{
        spawnerRoot = GameObject.FindGameObjectWithTag("Spawned");

		if(Input.GetKey(KeyCode.S))
		{
			canShoot = !canShoot;
		}
		if (onStart)
		{
			onStart = false;
			Start();
		}
		
		if(!PauseMenu.pauseMenuEnabled && !UpgradeGUINew.upgradeEnabled)
			Move();
		if (mTimer > fireRate && canShoot)
		{
			MainShoot();
			mTimer = 0.0f;
		}
		if (shootSecondary) //Input.GetMouseButtonUp(0) && shootSecondary)
		{
				SecondaryShoot();
		}
		mTimer += Time.deltaTime;
		vortexTimer += Time.deltaTime;
		shottyTimer += Time.deltaTime;
		secondaryTimer += Time.deltaTime;
	}
	void MainShoot()
	{
		switch (mainAttack)
		{
			case mainAttacks.Laser:
				playSounds.laserShoot = true;
				ShootBullets();
				break;
			case mainAttacks.Multilaser:
				playSounds.MultiLaserShoot = true;
				ShootDouble();
				break;
			case mainAttacks.Shottylaser:
				playSounds.ShottyLaserShoot = true;
				if(shottyTimer > 1.0f)
					ShootShotty();
				break;
		}
	}
	void SecondaryShoot()
	{
		switch (secondaryAttack)
		{
			case secondaryAttacks.Rocket:
				if((secondaryTimer > reload.rocket || initialShot))
				{
                    if (spawnerRoot != null ? spawnerRoot.transform.childCount > 0 : false)
                    {
                        reloadMax = reload.rocket;
                        playSounds.rocketShoot = true;
                        ShootRockets();
                        secondaryTimer = 0;
                        initialShot = false;
                    }
				}
				break;
			case secondaryAttacks.Clusterbomb:
				if(GameObject.FindGameObjectWithTag("cluster") == null)
			{
				if(Input.GetMouseButtonUp(0) && (secondaryTimer > reload.cluster || initialShot))
				{
					reloadMax = reload.cluster;
					ShootClusterbomb();
					secondaryTimer = 0;
					initialShot = false;
				}
			}
					break;
			case secondaryAttacks.Vortex:
				if( Input.GetMouseButtonUp(0) && (secondaryTimer > reload.vortex || initialShot))
				{
					reloadMax = reload.vortex;
					playSounds.vortexShoot = true;
					ShootVortex();
					secondaryTimer = 0;
					initialShot = false; 
				}
				break;
		}
	}
	
	void Move()
	{
		mDirection = Vector3.zero;
		if(Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
		{
			mDirection += Vector3.up;
		}
		if(Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
		{
			mDirection += Vector3.left;
		}
		if(Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
		{
			mDirection += Vector3.down;
		}
		if(Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
		{
			mDirection += Vector3.right;
		}

	
		if (Input.touchCount > 0)
		{
//			//Switch through touch events
//			int fingerCount = 0;
//			foreach (Touch touch in Input.touches)
//			{
//				if (touch.phase != TouchPhase.Ended && touch.phase != TouchPhase.Canceled)
//					fingerCount++;
//			}
//			if (fingerCount == 2)
//			{
//				switch (mainAttack)
//				{
//					//TODO: Need to add logic to see if weapon is bought
//
//					case mainAttacks.Laser:
//						mainAttack = mainAttacks.Multilaser;
//						break;
//					case mainAttacks.Multilaser:
//						mainAttack = mainAttacks.Shottylaser;
//						break;
//					case mainAttacks.Shottylaser:
//						mainAttack = mainAttacks.Laser;
//						break;
//				}
//			}
//			if (fingerCount == 3)
//			{
//				switch (secondaryAttack)
//				{
//					//TODO: Need to add logic to see if weapon is bought
//
//					case secondaryAttacks.Rocket:
//						secondaryAttack = secondaryAttacks.Clusterbomb;
//						break;
//					case secondaryAttacks.Clusterbomb:
//						secondaryAttack = secondaryAttacks.Vortex;
//						break;
//					case secondaryAttacks.Vortex:
//						secondaryAttack = secondaryAttacks.Rocket;
//						break;
//				}
//			}
			switch (Input.GetTouch(0).phase)
			{
				case TouchPhase.Began:
					TouchPosition = new Vector3(Input.touches[0].position.x, Input.touches[0].position.y, 0);
					TouchPosition = (Camera.main.ScreenToWorldPoint(TouchPosition));
					break;
				case TouchPhase.Moved:
					TouchPosition2 = new Vector3(Input.touches[0].position.x, Input.touches[0].position.y, 0);
					TouchPosition2 = (Camera.main.ScreenToWorldPoint(TouchPosition2));
					positionOffset = TouchPosition2 - TouchPosition;
					positionOffset.z = 0;
					transform.position = positionOffset + transform.position;
					TouchPosition = new Vector3(Input.touches[0].position.x, Input.touches[0].position.y, 0);
					TouchPosition = (Camera.main.ScreenToWorldPoint(TouchPosition));
					break;
				case TouchPhase.Ended:
					break;
			}
		}
		else
		{
			transform.position = Vector3.Lerp(transform.position, mDirection + transform.position, Time.deltaTime * playerSpeed);
		}
		
	}
	
	void ShootBullets()
	{
		Weapon bullet = ((GameObject)Instantiate(gameBullet, transform.position, Quaternion.Euler(new Vector3(offSetX,offSetY,offSetZ)))).GetComponent<Weapon>();//0,90,270
		bullet.currWeapon = Weapon.weaponState.Bullet;
		Physics.IgnoreCollision(collider, bullet.collider, true);
		bullet.fireDirection = Vector3.Cross(new Vector3(offSetX,offSetY,offSetZ), Vector3.up).normalized;
	}

	void ShootDouble()
	{
		float bulletOffset = -.1f;
		Weapon[] bullets = new Weapon[2];
		for (int i = 0; i < 2; i++)
		{
			//Debug.Log("AAAA "+bulletOffset);
			if(i ==1)
				bulletOffset = .1f;
			bullets[i] = ((GameObject)Instantiate(gameBullet, new Vector3(transform.position.x+bulletOffset, transform.position.y, transform.position.z),  Quaternion.Euler(new Vector3(offSetX,offSetY,offSetZ)))).GetComponent<Weapon>();
            bullets[i].GetComponent<DealsDamage>().DamageOnCollision = doubleDamage;
            bullets[i].currWeapon = Weapon.weaponState.Bullet;
			Physics.IgnoreCollision(collider, bullets[i].collider, true);
			bullets[i].fireDirection = Vector3.Cross(new Vector3(offSetX,offSetY,offSetZ), Vector3.up).normalized;
		}				
	}
	void ShootShotty()
	{
		Weapon[] bullets = new Weapon[5];
		for (int i = 0; i < bullets.Length; i++)
		{
			//Debug.Log("AAAA "+bulletOffset);
			bullets[i] = ((GameObject)Instantiate(gameBullet, new Vector3(transform.position.x + Random.Range(-.6f, .6f), transform.position.y + Random.Range(0.0f, .2f), 0), Quaternion.Euler(new Vector3(offSetX, offSetY, offSetZ)))).GetComponent<Weapon>();
			bullets[i].currWeapon = Weapon.weaponState.Bullet;
			Physics.IgnoreCollision(collider, bullets[i].collider, true);
			bullets[i].fireDirection = Vector3.Cross(new Vector3(offSetX, offSetY, offSetZ), Vector3.up).normalized;
		}
		shottyTimer = 0.0f;
	}

	void ShootClusterbomb()
	{
		screenPoint2 = Camera.main.WorldToScreenPoint(gameObject.transform.position);
		clickpoint = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint2.z));
		offset2 = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint2.z));
		clusterbomb = (GameObject)Instantiate(gameCluster, transform.position, Quaternion.Euler(new Vector3(90, 180, 0)));
		clusterbomb.rigidbody.AddForce(-offset2.normalized * clusterbomb.GetComponent<clusterbomb>().clusterBombSpeed);
	}
	void ShootRockets()
	{


		screenPoint2 = Camera.main.WorldToScreenPoint(gameObject.transform.position);

		//screenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position);
		//offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
		clickpoint = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint2.z));
		offset2 = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint2.z));


		screenPoint2 = Vector3.zero;
		clickpoint = Vector3.zero;
		Rocket rocket =((GameObject)Instantiate(gameRocket, transform.position, Quaternion.Euler(new Vector3(270f,90f,270f)))).GetComponent<Rocket>();
        //float shootDistance = 99f;
        //Vector3 shootDir = Vector3.zero;
        //GameObject enemy = null;
        //foreach(Transform child in spawnerRoot.transform)
        //{
        //        //if (Vector3.Distance(rocket.transform.position, child.transform.position) < shootDistance)
        //    //print("distance :" + (child.transform.position.y - rocket.transform.position.y));
        //    if ((child.transform.position.y - rocket.transform.position.y) < shootDistance)
        //        {
        //            shootDistance = (child.transform.position.y - rocket.transform.position.y);
        //            shootDir = child.transform.position;
        //            enemy = child.gameObject;
        //        }
        //}
		rocket.currWeapon = Weapon.weaponState.Rocket;
		Physics.IgnoreCollision(collider, rocket.collider, true);

		
        // rocket.destVector = offset2.normalized; // USE FOR CLICK Rockets
        //rocket.destVector = (rocket.transform.position - shootDir).normalized; // use for rockets auto-fire towards enemy

        //rocket.transform.rotation = rocket.transform.rotation;
        rocket.HomingOn();
        
        //rocket.destVector = clickpoint.normalized;
		
	}
	void ShootVortex()
	{
		screenPoint2 = Camera.main.WorldToScreenPoint(gameObject.transform.position);
		clickpoint = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint2.z));
		vortex = (GameObject)Instantiate(gameVortex, clickpoint, Quaternion.Euler(new Vector3(180, 180, 0)));
		
	}

	public override void TakeDamage(int dmg)
	{
        if (Manager.Vibrate)
        {
            Handheld.Vibrate();
        }
			float i = Random.value;
			evasion = (PlayerPrefs.GetInt("Evasion") / 100.0f) + .1f;
			if (i <= evasion)
			{
				evaded = true;
         
				dmg = 0;
			}
			//Debug.Log("Random: " + i + " evasion: " + evasion+" "+evaded);
			if (!evaded)
			{
				armor = PlayerPrefs.GetInt("Armor");
				dmg -= armor;
			}
		dmgTaking = dmg;
		evaded = false;
		if((CurrHealth -= dmg) <= 0)
		{
			Die();
		}
        InvokeRepeating("ToggleShader", 0.00001f, .3f);
    }
    public void ToggleShader()
    {
        if (renderer.material.shader == Shader.Find("Transparent/Diffuse") || renderer.material.shader == Shader.Find("Transparent/Bumped Diffuse"))
        {
            //renderer.material.color = Color.red;
            renderer.material.shader = Shader.Find("Particles/Additive");

        }
        else if (renderer.material.shader == Shader.Find("Particles/Additive"))
        {
            renderer.material.shader = Shader.Find("Transparent/Diffuse");
            CancelInvoke();
        }
    }
	void OnGUI()
    {
	//	GUI.Label(new Rect(Screen.width/2+50, Screen.height/2 +100, 50,50),CurrHealth.ToString());
		Vector3 playerPos = Camera.main.WorldToViewportPoint(gameObject.transform.position);
		reloadBar.transform.position = playerPos;
		reloadBar.guiTexture.pixelInset = new Rect(reloadBar.guiTexture.pixelInset.x, reloadBar.guiTexture.pixelInset.y, (secondaryTimer > reloadMax) ? initialRbarWidth : initialRbarWidth*(secondaryTimer / reloadMax), reloadBar.guiTexture.pixelInset.height);
        //GO.guiTexture.color = new Color(GO.guiTexture.color.r, GO.guiTexture.color.g, GO.guiTexture.color.b, 60f);
        //GO.transform.position = playerPos;
        ////GO.guiTexture.pixelInset = new Rect(Screen.height playerPos.x, playerPos.y, GO.guiTexture.pixelInset.width, GO.guiTexture.pixelInset.height);
        //GO.guiTexture.pixelInset = new Rect(GO.guiTexture.pixelInset.x, GO.guiTexture.pixelInset.y,  initialHbarWidth * ((float)CurrHealth / (float)Health),GO.guiTexture.pixelInset.height);

        //GUI.DrawTexture(new Rect(Screen.width / 2, Screen.height / 2, 200, 200), shipReg);

	}
	public override void Die()
	{
		Instantiate( explosion1,transform.position,Quaternion.identity);
		PlayerPrefs.SetInt("Currency",0);
		print(Spawner.currWave);
		PlayerPrefs.SetInt("Level", Spawner.currWave);
		// Destroy(gameObject);
		Debug.Log("You ran out of health you lose HEALTH: "+ CurrHealth);		
		Application.LoadLevel(2);
	}
}